<!--
 * @Author: jiu yin
 * @Date: 2024-04-11 14:04:23
 * @LastEditTime: 2024-04-29 14:30:06
 * @LastEditors: jiu yin zhen jing
 * @FilePath: \web-smart-tour\src\pagesA\ar_navigation\components\amap.vue
 * jiu
-->
<template>
	<view :class="{ content_map: true, radius: map_nav_type_computed != 'map_nav' }">
		<map id="map" ref="map" :longitude="naviMaps_obj.lng" :latitude="naviMaps_obj.lat" :markers="markers"
			:polyline="polyline" :scale="map_nav_type_computed == 'map_nav' ? 13 : 13" show-location
			:enable-3D="enableThreeD" :enable-satellite="enableSatellite" :enable-traffic="enableTraffic"
			:enable-overlooking="false" :max-scale="20" :min-scale="9" :enable-zoom="true" :enable-scroll="true"
			:enable-poi="false" :style="{ width: '100%', height: copay_height, zIndex: 1 }" @markertap="markerStap">
			<!-- 自定义气泡 -->
			<cover-view slot="callout">
				<template v-for="(item,index) in markers">
					<cover-view class="customCallout" :marker-id="item.id" v-if="markItem.id==item.id">
						{{ item.title }}
					</cover-view>
				</template>
			</cover-view>

		<view class="news_div" v-if="newsInfo" v-show="map_nav_type_computed == 'map_nav' ? true : false">
			<view class="news_div_1" @tap="navigateTo(`/pagesA/news/detail?id=${newsInfo.id}`)">{{newsInfo.title}}
			</view>
			<view class="news_div_2" @tap="navigateTo(`/pagesA/news/list?sid=${newsInfo.spot_id}`)"><u-icon
					name="arrow-right" size="20" color="#fff"></u-icon></view>
		</view>
			
		</map>
		
		<scenic ref="scenic" v-show="is_scenic" :markItem="markItem" @go_nav="go_nav" @close_nav="close_nav" />
	</view>
</template>

<script>
	import {
		mapGetters,
		mapActions
	} from 'vuex';
	import {
		openLocation,
		navigateTo
	} from '@/hooks';
	import {
		ossurl
	} from '@/utils/index';
	import {
		naviMaps,
		naviScenicSpots,
		naviRenew,
		naviScenicSpotsClock,
		naviStart,
		noticeNew
	} from '@/api/home';
	import {
		throttle,
		getSetting
	} from '@/utils';
	import {
		nationwide_bounds,
		nationwide_src
	} from '@/enum';
	import scenic from './scenic.vue';
	import coordtransform from '@/utils/coordtransform';
	let {
		getDistance,
		dealPath,
		getRandomCoordinate
	} = coordtransform();
	let throttle_fn = throttle();
	let throttle_fn1 = throttle();
	let naviStart_path = [];
	let marker_item = {
		longitude: 0,
		latitude: 0,
		iconPath: '',
		width: 25,
		height: 26,
		id: 0,
		label: {
			content: '起',
			anchorX: -6,
			anchorY: -23,
			fontSize: 11,
		},
	};

	let user_marker = {
		longitude: 0,
		latitude: 0,
		iconPath: '',
		width: 25,
		height: 26,
		id: 1,
		label: {
			content: '我',
			anchorX: -6,
			anchorY: -23,
			fontSize: 11,
		},
	};

	export default {
		components: {
			scenic
		},
		props: ['height'],
		data() {
			return {
				navigateTo,
				newsInfo: {},
				mapContext: null,
				longitude: '',
				latitude: '',
				init_distance: 0,
				markers: [],
				polyline: [],
				enableSatellite: false, //开启卫星地图
				enableTraffic: false, //开启实时路况
				enableThreeD: true, //开启3d
				copay_height: '428rpx',

				naviMaps_obj: {
					lng: '',
					lat: ''
				}, //景区导航地图信息
				naviScenicSpots_list: [], //景区标记数组markers
				position: '', //自己位置
				destination: {}, //终点
				discrepancy_distance: 10, //相差距离
				click_masker: true, //第一次点击标记 开始计时和行走距离
				scenic_detail: JSON.parse(uni.getStorageSync('scenic_detail')) || {},
				markItem: {},
				start_id: 0, //发起导航id
				is_scenic: false,
				points: [],
				start_info: {},
				navigation_end: false, //是否导航结束
				// 模拟数据
				mock_data: {
					ti: 0,
					index: 0,
					path: [],
				},
			};
		},

		async onReady() {
			this.mapContext = uni.createMapContext('map', this);
			var that = this;
			try {
				await getSetting({
					scope: 'scope.userLocation',
					url: '/pagesA/ar_navigation/index',
					content: '否重新开启定位权限，你的位置将用于地图导航功能',
					toast: '未授权地理权限,地图功能将无法使用',
				});
				this.getRegeo(); //初始化
				this.get_naviMaps();
				this.onLocationChange();
				this.getNews();

				//await this.get_naviScenicSpots(); //获取标记
				//景点打卡过来
				if (this.scenic_detail.from == 'punch') {
					setTimeout(function() {
						that.markerStap(that.scenic_detail);
						that.$refs.scenic.description = true;
					}, 2000);

				}
			} catch (err) {
				console.log(err);
			}
			//监听
			uni.$on('top_nav_change', function(data) {
				console.log('监听到事件', data);
				that.markers = [];
				that.get_naviScenicSpots({
					spot_id: that.scenic_detail.spot_id,
					points_type: 3,
					locate_lng: that.longitude,
					locate_lat: that.latitude,
					category_id: data.id,
				}, ossurl(data.map_icon));
			})
			
			uni.$on("point_change",(data)=>{
				
				this.markPoint(data.id);
				
			})

		},
		computed: {
			...mapGetters(['is_logined', 'userInfo', 'mock_open']),
			map_nav_type_computed() {
				return this.$store.getters.map_nav_type;
			},
			amapPlugin() {
				return this.$store.getters.amapPlugin;
			},
			rec_url() {
				return this.$store.getters.rec_url;
			},
			fileDeploy() {
				console.log(this.$store.getters.fileDeploy, '公共文件配置');
				return this.$store.getters.fileDeploy;
			},
		},
		watch: {
			'$store.getters.mock_open': {
				handler(newVal, oldVal) {
					console.log('mock_open==', newVal);
					if (newVal == oldVal) return;
					if (newVal) {
						this.mock_data.ti = setInterval(() => {
							this.mock_data.index++;
							this.mockPostion();
						}, 1000);
					} else {
						this.mock_data.path = [];
						clearInterval(this.mock_data.ti);
					}
				},
			},
			//切换导航模式
			'map_nav_type_computed'(newVal, oldVal) {
				if (newVal == oldVal) return;
				this.mapContext.moveToLocation({
					longitude: +this.naviMaps_obj.lng,
					latitude: +this.naviMaps_obj.lat
				});
				if (newVal == 'map_nav') {
					this.copay_height = this.height;
				} else {
					setTimeout(() => {
						this.copay_height = this.height;
					}, 400);
				}
			},
			//自己定位变化
			'position'(newVal, oldVal) {
				if (newVal == oldVal) return;
				// this.destination && this.getWalkingRoute();
			},
		},

		methods: {
			//初始化 高德  定位
			async getRegeo() {
				var that = this;
				uni.getLocation({
					type: 'gcj02',
					success: function(res) {
						console.log("获取地图geo信息===", res)
						const data = res;
						that.position = [data.longitude, data.latitude].join(',');
						that.longitude = data.longitude;
						that.latitude = data.latitude;
						that.get_naviScenicSpots({
							spot_id: that.scenic_detail.spot_id,
							points_type: 3,
							locate_lng: that.longitude,
							locate_lat: that.latitude,
							category_id: 1,
						});

					}
				});
			},

			getNews() {

				noticeNew({
					spot_id: this.scenic_detail.spot_id
				}).then((res) => {
					let data = res.data;
					this.newsInfo = data;
				});

			},

			//获取标记点
			async get_naviScenicSpots(param, icon = '') {

				/* console.log('@@@@@@@@@@@@@@@',this.longitude);
				console.log(this.latitude);
				var param = {};
				param.spot_id = this.scenic_detail.spot_id;
				param.points_type = 1;			
				
				
				param.locate_lng =  this.longitude;
				param.locate_lat = this.latitude; */
				if (icon == '') {
					icon = ossurl('/ai_tour/assets/static/images/map/scenic_A.png');
				}



				let {
					data
				} = await naviScenicSpots(param);
				this.naviScenicSpots_list = data;
				data.forEach((item) => {
					this.markers.push({
						id: item.id,
						title: item.title,
						longitude: item.lng,
						latitude: item.lat,
						width: 30,
						height: 32,
						iconPath: icon,
						label: {
							content: item.title,
							color: '#000000',
							bgColor: '#FFFFFF',
							borderRadius: '5px',
							padding: '5px',
							anchorX: -25,
							anchorY: 0,
						},
						customCallout: {
							anchorY: 0, // Y轴偏移量
							anchorX: 0, // X轴偏移量
							display: 'ALWAYS', // 'BYCLICK':点击显示; 'ALWAYS':常显
						},
					});
				});
			},
			//获取自定义贴图
			get_naviMaps() {
				var _this =this;
				naviMaps({
					spot_id: this.scenic_detail.spot_id
				}).then(res => {
				   var data = res.data;
				   console.log('自定义贴图', data);
				   _this.naviMaps_obj = data;
				   _this.mapContext.moveToLocation({
				   					longitude: +data.lng,
				   					latitude: +data.lat
				   });
				   _this.nationwide({
				   					id: 998,
				   					src: nationwide_src,
				   					bounds: nationwide_bounds
				   	});
				   _this.option_GroundOverlay(data);
				   console.log("设置自定义Map", data);
				   //如果没开通就弹窗
				   if (res.code == 48004) {
				   		uni.$emit("ai_showModal",{status:true});
				   }
				  
			   })
			  

			},
			//全国覆盖图
			nationwide({
				id,
				src,
				bounds
			}) {
				this.mapContext.addGroundOverlay({
					id,
					src,
					bounds,
					success(res) {
						console.log('wp', res);
					},
					fail(err) {
						console.log('wperr', err);
					},
				});
			},
			//传参添加自定义图层
			option_GroundOverlay(data) {
				let bounds = {
					northeast: {
						latitude: data.top_right_lat,
						longitude: data.top_right_lng,
					},
					southwest: {
						latitude: data.bottom_left_lat,
						longitude: data.bottom_left_lng,
					},
				};
				this.nationwide({
					id: 1,
					src: this.rec_url + data.hd_url,
					bounds
				});
			},

			//替换标记
			replace_marker(id, _marker_item, content) {
				let destination_index = this.markers.findIndex((item) => item.id == id);
				let copay = {
					...marker_item,
					..._marker_item,
					label: {
						content,
						anchorX: -6,
						anchorY: -23,
						fontSize: 11,
					},
				};
				if (destination_index != -1) {
					this.markers.splice(destination_index, 1, copay);
				} else {
					this.markers.push(copay);
				}
			},

			//点击标记
			async markerStap(res) {
				console.log('---------------------',res);
				let id = res.detail.markerId;
				this.markPoint(id);
			},
			markPoint(id){
			
				//请求的标记点
				const markItem = this.naviScenicSpots_list.find((item) => item.id == id);
				this.markItem = markItem;
				
				this.mapContext.moveToLocation({
					longitude: +markItem.lng,
					latitude: +markItem.lat
				});
				 this.is_scenic = true;
			},
			go_nav() {
				this.is_scenic = false;
				this.markerStap_fn();
			},
			close_nav() {
				this.is_scenic = false;
			},
			async markerStap_fn() {
				if (!this.range_distance()) {
					const confirm_popup = this.$root.$refs['confirm_popup'];
					confirm_popup.tipsShow('未在景区范围内,是否前往景区', '', () => {
						console.log('前往景区');
						confirm_popup.tipsHide();
						openLocation({
							name: this.markItem.title,
							latitude: this.markItem.lat,
							longitude: this.markItem.lng,
							address: this.markItem.title,
						});
					});
					return;
				}

				this.init_distance = 0; //距离导航
				//景区开始导航发起
				let {
					data
				} = await naviStart({
					spot_id: this.scenic_detail.spot_id
				});
				naviStart_path = [];
				this.start_id = data.id;
				this.navigation_end = false;

				this.destination = {
					longitude: this.markItem.lng,
					latitude: this.markItem.lat,
					end_distance: this.markItem.end_distance, //剩余距离多少时结束导航
				};
				this.start_info = {
					id: data.id,
					longitude: this.longitude,
					latitude: this.latitude,
				};
				// this.longitude this.latitude
				//起点
				this.replace_marker(0, {
					longitude: +this.longitude.lng,
					latitude: +this.longitude.lat,
					iconPath: '/static/images/begin_icon.png',
					id: 0
				}, '起');
				//终点
				this.replace_marker(
					999, {
						longitude: this.destination.longitude,
						latitude: this.destination.latitude,
						iconPath: '/static/images/finish_icon.png',
						id: 999
					},
					'终'
				);

				this.getWalkingRoute();
			},

			//步行路线
			getWalkingRoute() {
				const destination = `${this.destination.longitude},${this.destination.latitude}`;
				// this.position
				this.amapPlugin.getWalkingRoute({
					origin: this.position,
					destination,
					success: (data) => {
						console.log(data, '步行路线');
						this.points = this.dealPoints(data.paths[0].steps);
						this.calcDistance();
						// 绘制起点到终点的线路
						this.polyline = [{
							points: this.points,
							color: '#ed6414',
							width: 6,
							arrowLine: true,
						}, ];
					},
					fail: function(err) {
						console.log(err.errMsg);
					},
				});
			},
			calcDistance() {
				// return false;
				// const points = this.points;
				// let distance = points.reduce((prev, item) => {
				// 	prev += ~~item.distance;
				// 	return prev;
				// }, 0);
				// this.init_distance = distance; //线路距离

				// console.log(distance);
			},
			//线
			dealPoints(map_steps) {
				const steps = dealPath(map_steps);
				const points = [];
				steps.forEach(function(t, e) {
					t.path.forEach(function(t) {
						points.push({
							latitude: t[0],
							longitude: t[1],
						});
					});
				});
				const last = points[points.length - 1];
				const distance = getDistance({
					longitude: last.longitude,
					latitude: last.latitude
				}, {
					longitude: this.destination.longitude,
					latitude: this.destination.latitude
				});
				console.log('最后节点距离目的地距离', distance);
				if (distance > 5) {
					console.log('如果导航的最后地点与目的地距离超过5m则路径内加入目的地信息');
					points.push({
						latitude: this.destination.latitude,
						longitude: this.destination.longitude,
					});
				}
				this.calcPoints(points);
				return points;
			},
			calcPoints(points) {
				const start_info = this.start_info;
				let prev_point = {
					longitude: start_info.longitude,
					latitude: start_info.latitude,
				};
				points.forEach((item, index) => {
					if (!item['latitude'] && item['lat']) {
						item['latitude'] = item['lat'];
						item['longitude'] = item['lng'];
						item['ch'] = 1;
					}
					const distance = getDistance({
						latitude: prev_point.latitude,
						longitude: prev_point.longitude
					}, {
						latitude: item.latitude,
						longitude: item.longitude
					});
					item.distance = +Number(distance).toFixed(2);
					prev_point = {
						longitude: item.longitude,
						latitude: item.latitude,
					};
					//删除多余属性
					if (item.ch) {
						delete item.latitude;
						delete item.longitude;
						delete item.ch;
					}
				});

				return points;
			},

			//模拟位置数据变化
			mockPostion() {
				// const postion = { accuracy: 65, altitude: 0, horizontalAccuracy: 65, latitude: 30.64242, longitude: 104.04311, speed: -1, verticalAccuracy: 65 };
				if (!this.points.length) {
					uni.$u.toast('请选择线路才能开始模拟');
					return;
				}
				if (this.mock_data.path.length == 0) {
					const path = [];
					this.points.forEach((item) => {
						path.push({
							latitude: item.latitude,
							longitude: item.longitude,
							speed: 2.5,
							accuracy: 2,
						});
					});
					this.mock_data.path = path;
					// this.mock_data.index = path.length - 10; //加速模拟
					console.log('模拟数据最后一条', path[path.length - 1]);
				}
				if (this.mock_data.index >= this.mock_data.path.length) {
					this.mock_data.index = this.mock_data.path.length - 1;
				}
				const position = this.mock_data.path[this.mock_data.index];
				console.log('模拟位置==', this.mock_data.index, this.mock_data.path.length, position);
				this.mock_data.index += 1;

				this.update_position(position);
			},
			//监听位置权限开启
			onLocationChange() {
				uni.startLocationUpdate({
					type: 'gcj02',
					success: (res) => {
						uni.onLocationChange((data) => {
							console.log('位置变更监听==', data);
							// console.log(data.accuracy, '精度');
							if (!this.is_logined) return;
							if (!this.naviMaps_obj.lng) return; //没有景点坐标
							// console.log('是否开启模拟行走', this.mock_open);
							if (this.mock_open) return; //如果开启了模拟则不更新位置
							if (data.accuracy > this.fileDeploy.maps.accuracy) return; //精度小于100 中等
							this.update_position(data);
						});
					},
					fail: (err) => {
						consoler.log(err);
					},
				});
			},

			//定位更新
			update_position(data) {


				this.replace_marker(
					1, {
						...user_marker,
						longitude: this.longitude,
						latitude: this.latitude,
						iconPath: this.userInfo.avatar ? ossurl(this.userInfo.avatar, 'user_face') :
							'/static/images/logo.png',
					},
					''
				);

				//范围内打卡
				if (this.range_distance()) {
					throttle_fn1(() => {
						this.clock_in_distance(data);
					}, this.fileDeploy.maps.walk_renew_ms);
				}
				// if (distance < this.discrepancy_distance) return

				//海拔 速度
				this.$store.commit('map/set_change_map', {
					altitude: ~~data.altitude,
					speed: data.speed > 0 ? ~~data.speed : 0
				});
				//发起导航才有浏览日志精度100以内
				if (this.start_id && !this.navigation_end) {
					//距离目标点距离
					let distance = getDistance({
						longitude: this.longitude,
						latitude: this.latitude
					}, {
						longitude: this.destination.longitude,
						latitude: this.destination.latitude
					});

					this.init_distance += getDistance({
						longitude: this.longitude,
						latitude: this.latitude
					}, {
						longitude: data.longitude,
						latitude: data.latitude
					});
					this.init_distance = parseInt(this.init_distance);

					console.log('距离目标点距离11', distance);
					if (distance < this.destination.end_distance) {
						console.log('导航结束');
						this.navigation_end = true;
					}

					//点击位置总移动距离
					this.$store.commit('map/set_change_map', {
						init_distance: this.init_distance
					});
					naviStart_path.push({
						lng: data.longitude,
						lat: data.latitude,
						s: 0,
						t: 0,
						a: data.accuracy
					});
					this.calcPoints(naviStart_path);
					throttle_fn(() => {
						this.browsing_log({
							speed: data.speed,
							init_distance: this.init_distance
						});
					}, this.fileDeploy.maps.walk_renew_ms);
				}


				//更新位置
				this.position = [data.longitude, data.latitude].join(',');
				this.longitude = data.longitude;
				this.latitude = data.latitude;

			},
			//浏览日志
			browsing_log(data) {
				let params = {
					id: this.start_id,
					spot_id: this.scenic_detail.id,
					speed: data.speed > 0 ? ~~data.speed : 0,
					distance: data.init_distance,
					path: naviStart_path,
				};
				console.log('我去上传', params);
				naviRenew(params);
			},
			//打卡
			async clock_in_distance() {
				const data = {
					latitude: this.latitude,
					longitude: this.longitude
				};
				let len = this.naviScenicSpots_list.length;
				console.log('naviScenicSpots_list====', this.naviScenicSpots_list);
				for (let i = 0; i < len; i++) {
					const item = this.naviScenicSpots_list[i];
					if (item.clock_status) {
						console.log('打卡数据*************', item);
						console.log('打卡数据', item.post_data);
						continue;
					}
					//默认添加当前景点数据
					item.multi_node.push({
						lat: item.lat,
						lng: item.lng
					});
					let multi_node = item.multi_node;
					for (let j = 0; j < multi_node.length; j++) {
						const item2 = multi_node[j];
						// console.log('坐标计算', { latitude: data.latitude, longitude: data.longitude }, { latitude: +item2.lat, longitude: +item2.lng });
						let distance = getDistance({
							latitude: data.latitude,
							longitude: data.longitude
						}, {
							latitude: +item2.lat,
							longitude: +item2.lng
						});
						distance = +distance.toFixed(2);
						console.log('距离景点距离******', distance);
						if (distance <= item.clock_in_distance) {
							item.clock_status = 1;
							let params = {
								spot_id: item.spot_id,
								points_id: item.id,
								lng: data.longitude,
								lat: data.latitude,
								clock_distance: distance
							};
							item.post_data = params;

							await naviScenicSpotsClock(params);
							//触发打开开关
							this.$store.commit('map/set_clockModal', {
								show: true,
								title: item.title,
								id: item.id,
								spot_id: item.spot_id,
							});
							console.log("1231313===",this.$store.getters.clockModal)
							return;
						}
					}
				}
			},
			//是否在景点范围
			range_distance() {
				let distance = getDistance({
					latitude: this.latitude,
					longitude: this.longitude
				}, {
					latitude: +this.naviMaps_obj.lat,
					longitude: +this.naviMaps_obj.lng
				});
				// console.log(distance, this.naviMaps_obj.spot_data.range_distance, '范围距离===');
				return distance <= this.naviMaps_obj.spot_data.range_distance ? true : false;
			},
		},
		beforeDestroy() {
			uni.stopLocationUpdate({
				success() {
					console.log('关闭监听实时位置变化，前后台都停止消息接收');
				},
			});
			uni.offLocationChange(this.update_position);
			clearInterval(this.mock_data.ti);
		},
	};
</script>

<style lang="scss">
	.content_map {
		height: 100%;
		background-color: #0cca92;
	}

	.radius {
		border-radius: 110rpx 110rpx 0rpx 0rpx;
		overflow: hidden;
	}

	.customCallout {
		background: #e45f3a;
		padding: 12rpx;
		color: #fff;
		font-weight: 700;
		font-size: 28rpx;
		border-radius: 16rpx;
	}



	.news_div {
		width: 532rpx;
		height: 56rpx;
		background-color: rgba(2,43,32, 0.6);
		border-radius: 16rpx 16rpx 16rpx 16rpx;
		margin: 40rpx auto 0 auto;
		display: flex;
		justify-content: space-between;
		align-items: center;
		
		.news_div_1{
			color: #FFFFFF;
			font-size: 28rpx;
			margin-left: 20rpx;
			width: 425rpx;
			display: flex;
			align-items: center;
			height: 100%;
			overflow: hidden;
			text-overflow: ellipsis;//文字超出省略号
			white-space:nowrap
		}
		.news_div_2{
			color: #FFFFFF;
			margin-right: 20rpx;
			
		}
	}
</style>